package com.ccx.demo.config;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.CannedAccessControlList;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 阿里云文件服务
 * <pre>
 * https://help.aliyun.com/document_detail/32011.html
 * </pre>
 *
 * @author 谢长春 2020-11-23
 */
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "spring.app.files.type", havingValue = "alioss")
@Slf4j
@Getter
@Setter
@ConfigurationProperties(prefix = "spring.app.files.alioss")
public class AliOssConfiguration {
    /**
     * 这里置空，文件存储在 bucketName
     */
    private String directory;
    /**
     * 文件服务访问地址
     */
    private String server;
    /**
     * 区域
     */
    private String region;
    /**
     * 存储桶名称， 注： 阿里云 OSS 的 bucket 必须是全局唯一，不能跟其他用户重叠，最好在阿里云控制台提前建好
     */
    private String bucketName;
    /**
     * 外网节点: https://help.aliyun.com/document_detail/31837.html
     */
    private String external;
    /**
     * ecs 内网节点: https://help.aliyun.com/document_detail/31837.html
     */
    private String internal;
    /**
     * 开发环境使用外网节点
     */
    private String endpoint;
    /**
     *
     */
    private String sts;
    /**
     * Access key就像用户ID，可以唯一标识你的账户。
     */
    private String accessKey;
    /**
     * Secret key是你账户的密码。
     */
    private String secretKey;

    @Bean
    public CommandLineRunner printMinioConfigurationCommandLineRunner() {
        return args -> log.info("\nspring.app.files.alioss.directory【这里置空，文件存储在 bucketName】 : {}"
                        + "\nspring.app.files.alioss.server【文件服务访问地址】 : {}"
                        + "\nspring.app.files.alioss.region【区域】 : {}"
                        + "\nspring.app.files.alioss.bucketName【存储桶名称】 : {}"
                        + "\nspring.app.files.alioss.external【外网节点】 : {}"
                        + "\nspring.app.files.alioss.internal【内网节点】 : {}"
                        + "\nspring.app.files.alioss.endpoint【当前使用节点】 : {}"
                        + "\nspring.app.files.alioss.sts【-】 : {}"
                        + "\nspring.app.files.alioss.accessKey【-】 : {}"
                        + "\nspring.app.files.alioss.secretKey【-】 : {}"
                , directory
                , server
                , region
                , bucketName
                , external
                , internal
                , endpoint
                , sts
                , accessKey
                , secretKey
        );
    }

    @Bean(destroyMethod = "shutdown")
    @SneakyThrows
    public OSS aliOssClient() {
        // 创建OSSClient实例。
        final OSS ossClient = new OSSClientBuilder().build(endpoint, accessKey, secretKey);
        // 检查存储桶是否已经存在
        final boolean isBucketExist = ossClient.doesBucketExist(bucketName);
        if (!isBucketExist) {
            // 创建存储桶
            ossClient.createBucket(bucketName);
            // 设置权限: 公有读
            ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
            {// 设置跨域访问
//                final SetBucketCORSRequest request = new SetBucketCORSRequest(bucketName);
//                SetBucketCORSRequest.CORSRule rule = new SetBucketCORSRequest.CORSRule();
//                rule.addAllowdOrigin("*");
//                rule.addAllowedMethod("*");
//                rule.addAllowedHeader("GET");
//                rule.setMaxAgeSeconds(3600);
//                ossClient.setBucketCORS(request);
            }
            {
                // 设置桶内静态资源可以直接访问
//                final SetBucketWebsiteRequest request = new SetBucketWebsiteRequest(bucketName);
//                request.setIndexDocument("index.html");
//                request.setErrorDocument("error.html");
//                request.AddRoutingRule();
//                ossClient.setBucketWebsite(request);
            }
            {
                // BucketPolicy 授权策略： https://help.aliyun.com/document_detail/85111.html
                // {"Statement": [{"Action": ["s3:GetBucketLocation", "s3:ListBucket"], "Effect": "Allow", "Principal": "*", "Resource": "arn:aws:s3:::%s"}, {"Action": "s3:GetObject", "Effect": "Allow", "Principal": "*", "Resource": "arn:aws:s3:::%s/myobject*"}], "Version": "2012-10-17"}
                // ossClient.setBucketPolicy(bucketName, String.format("{\"Version\": \"2012-10-17\", \"Statement\": [{\"Action\": \"s3:GetObject\", \"Effect\": \"Allow\", \"Principal\": \"*\", \"Resource\": \"arn:aws:s3:::%s/*\"}]}"
                //         , bucketName
                // ));
            }
        }
        log.info("ali oss 存储桶 【{}】 创建成功", bucketName);
        return ossClient;
    }
}
